From 8dc7e8a4a8cd0ed8b39a6b937bf1c537b68cd378 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 10 Sep 2014 07:01:32 -0700 Subject: [PATCH] Use libgit2 for `git ls-files` One forgotten spot to modify when migrating from the CLI to libgit2 --- src/cargo/sources/path.rs | 51 +++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index a81ea31aa..f340a36f1 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -2,10 +2,11 @@ use std::cmp; use std::fmt::{mod, Show, Formatter}; use std::io::fs; use glob::Pattern; +use git2; use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry}; use ops; -use util::{CargoResult, internal, internal_error, process}; +use util::{CargoResult, internal, internal_error}; pub struct PathSource { id: SourceId, @@ -68,11 +69,10 @@ impl PathSource { /// are relevant for building this package, but it also contains logic to /// use other methods like .gitignore to filter the list of files. pub fn list_files(&self, pkg: &Package) -> CargoResult> { - let candidates = try!(if self.path.join(".git").exists() { - self.list_files_git(pkg) - } else { - self.list_files_walk(pkg) - }); + let candidates = match git2::Repository::open(&self.path) { + Ok(repo) => try!(self.list_files_git(pkg, repo)), + Err(..) => try!(self.list_files_walk(pkg)), + }; let pats = pkg.get_manifest().get_exclude().iter().map(|p| { Pattern::new(p.as_slice()) @@ -86,26 +86,29 @@ impl PathSource { }).collect()) } - fn list_files_git(&self, pkg: &Package) -> CargoResult> { - let cwd = pkg.get_manifest_path().dir_path(); - let mut cmd = process("git").cwd(cwd.clone()); - cmd = cmd.arg("ls-files").arg("-z") - .arg("-x").arg("/target") - .arg("-x").arg("/Cargo.lock"); - - // Filter out all other packages with a filter directive - for pkg in self.packages.iter().filter(|p| *p != pkg) { - if cwd.is_ancestor_of(pkg.get_manifest_path()) { - let filter = pkg.get_manifest_path().dir_path() - .path_relative_from(&self.path).unwrap(); - cmd = cmd.arg("-x").arg(filter); + fn list_files_git(&self, pkg: &Package, repo: git2::Repository) + -> CargoResult> { + let index = try!(repo.index()); + let mut ret = Vec::new(); + 'outer: for i in range(0, index.len()) { + let entry = match index.get(i) { Some(e) => e, None => continue }; + let fname = entry.path.as_bytes_no_nul(); + let path = pkg.get_manifest_path().dir_path().join(fname); + + // Filter out Cargo.lock and target always + if fname == b"Cargo.lock" { continue } + if fname == b"target" { continue } + + // Filter out all other packages + for pkg in self.packages.iter().filter(|p| *p != pkg) { + let pkg_path = pkg.get_manifest_path().dir_path(); + if pkg_path.is_ancestor_of(&path) { continue 'outer; } } - } - log!(5, "listing git files with: {}", cmd); - let output = try!(cmd.arg(".").exec_with_output()); - let output = output.output.as_slice(); - Ok(output.split(|x| *x == 0).map(|p| cwd.join(p)).collect()) + // We found a file! + ret.push(path); + } + Ok(ret) } fn list_files_walk(&self, pkg: &Package) -> CargoResult> { -- 2.30.2